package com.mcflywzx.airhockey.util;

import static android.opengl.GLES20.glCreateShader;
import android.util.Log;
import static android.opengl.GLES20.*;


public class ShaderHelper {
	private static final String TAG = "ShaderHelper";
	
	public static int compileVertexShader(String shaderCode) {
		return compileShader(GL_VERTEX_SHADER, shaderCode);
	}
	
	public static int compileFragmentShader(String shaderCode) {
		return compileShader(GL_FRAGMENT_SHADER, shaderCode);
	}
	
	private static int compileShader(int type, String shaderCode) {
		//创建一个新的着色器对象
		final int shaderObjectID = glCreateShader(type);
		
		if(shaderObjectID == 0){
			if(Tools.CanLog){
				Log.w(TAG, "无法创建新shader");
			}
			
			return 0;
		}
		//上传和编译着色器
		glShaderSource(shaderObjectID, shaderCode);
		glCompileShader(shaderObjectID);
		//取出编译状态
		final int[] compileStatus = new int[1];
		glGetShaderiv(shaderObjectID, GL_COMPILE_STATUS, compileStatus, 0);
		//取出着色器日志
		if(Tools.CanLog){
			Log.v(TAG, "编译的结果是:" + "\n" + shaderCode + "\n:" + glGetShaderInfoLog(shaderObjectID));
		}
		//验证编译状态并返回着色器对象ID
		if(compileStatus[0] == 0) {
			//如果他失败了,删除这个shader object
			glDeleteShader(shaderObjectID);
			
			if(Tools.CanLog){
				Log.w(TAG, "编译失败");
			}
		}
		return shaderObjectID;
	}

	public static int linkProgram(int vertexShaderID, int fragmentShaderID) {

		//新建程序对象并附上着色器
		final int programObjectId = glCreateProgram();
		
		if(programObjectId == 0){
			if(Tools.CanLog){
				Log.w(TAG, "无法创建新程序");
			}
			
			return 0;
		}
		
		glAttachShader(programObjectId, vertexShaderID);
		glAttachShader(programObjectId, fragmentShaderID);
		//链接程序
		glLinkProgram(programObjectId);
		
		final int[] linkStatus = new int[1];
		glGetShaderiv(programObjectId, GL_LINK_STATUS, linkStatus, 0);
		//取出着色器日志
		if(Tools.CanLog){
			Log.v(TAG, "链接的结果是:" + "\n"  + glGetProgramInfoLog(programObjectId));
		}
		//验证链接状态并返回程序对象ID
		if(linkStatus[0] == 0) {
			//如果他失败了,删除这个shader object
			glDeleteShader(programObjectId);
				
			if(Tools.CanLog){
				Log.w(TAG, "链接程序失败");
			}
		}
		return programObjectId;
	}
	
	public static boolean validateProgram(int programObjectId) {
		//验证OpenGL程序的对象
		glValidateProgram(programObjectId);
		
		final int[] validateStatus = new int[1];
		glGetShaderiv(programObjectId, GL_VALIDATE_STATUS,  validateStatus, 0);
		//取出验证日志
		if(Tools.CanLog){
			Log.v(TAG, "验证程序的结果是:" + "\n"  + validateStatus[0] + "\nLog" + glGetProgramInfoLog(programObjectId));
		}
		return validateStatus[0] != 0;
	}

	public static int buildProgram(String vsSource, String fsSource) {
		int program;
		
		//编译着色器
		int vertexShader = ShaderHelper.compileVertexShader(vsSource);
		int fragmentShader = ShaderHelper.compileFragmentShader(fsSource);
				
		program = linkProgram(vertexShader, fragmentShader);
		//获取验证程序日志
		if(Tools.CanLog) {
			ShaderHelper.validateProgram(program);
		}
		
		return program;
	}
}
